package com.itheima.ydd.controller;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.ydd.common.PageResult;
import com.itheima.ydd.common.ResultData;
import com.itheima.ydd.dto.RoleVo;
import com.itheima.ydd.dto.SysMenuVo;
import com.itheima.ydd.entity.Role;
import com.itheima.ydd.entity.SysMenu;
import com.itheima.ydd.entity.SysRoleMenu;
import com.itheima.ydd.service.RoleService;
import com.itheima.ydd.service.SysMenuService;
import com.itheima.ydd.service.SysRoleMenuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@Slf4j
@RequestMapping("sys_role")
public class RoleController {
    @Autowired
    private RoleService roleService;
    @Autowired
    private SysRoleMenuService sysRoleMenuService;
    @Autowired
    private SysMenuService sysMenuService;

    /**
     * 分页查询
     *
     * @return
     */
    @GetMapping("list")
    public ResultData list(@RequestParam(value = "page", required = false, defaultValue = "1") String page,
                           @RequestParam(value = "limit", required = false, defaultValue = "5") String limit,
                           @RequestParam(required = false) String name) {
        LambdaQueryWrapper<Role> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.like(ObjectUtil.isNotEmpty(name), Role::getName, name);
        lambdaQueryWrapper.orderByDesc(Role::getUpdate_date);
        //设置分页参数;
        long pageNumber = NumberUtil.parseLong(page);
        long pageSize = NumberUtil.parseLong(limit);
        Page<Role> pageInfo = new Page<>(pageNumber, pageSize);
        //查询分页信息
        Page<Role> rolePage = roleService.page(pageInfo, lambdaQueryWrapper);
        //将查询到的结果手动封装到前台需要的对象PageResult中
        long counts = rolePage.getTotal();//总记录条数
        long pageSise = rolePage.getSize();//每页显示条数
        long currentPage = rolePage.getCurrent();//当前页面数
        List<Role> data = rolePage.getRecords();//存放查询出的数据

        PageResult pageResult = PageResult.init(counts, pageSise, currentPage, data);
        log.info(pageResult.toString());

        return ResultData.ok("分页展示成功", pageResult);
    }

    /**
     * 角色列表-全部--不分页
     *
     * @return
     */
    @GetMapping("allData")
    public ResultData allData() {
        //要查询所有的角色
        LambdaQueryWrapper<Role> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.orderByDesc(Role::getUpdate_date);
        List<Role> list = roleService.list(lambdaQueryWrapper);
        return ResultData.ok("全部角色列表", list);
    }

    /**
     * 角色详情rowInfo---有bug[说是修改的bug但是问题出在详情]
     *
     * @param id
     * @return
     */
    @GetMapping("rowInfo")
    public ResultData rowInfo(@RequestParam String id) {

        Role byId = roleService.getById(id);
        RoleVo roleVo = new RoleVo();
        BeanUtils.copyProperties(byId, roleVo);
        //拷贝完,还差权限的列内容

        //通过sys_role_menu这张第三方表能够通过roleid查到多个rolemenu对象
        LambdaQueryWrapper<SysRoleMenu> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysRoleMenu::getRole_id, id);
        List<SysRoleMenu> roleMenuList = sysRoleMenuService.list(lambdaQueryWrapper);
        //通过roleMenuList找到所有的menu对象
        List<SysMenuVo> sysMenuVoList = roleMenuList.stream().map(roleMenu -> {
            String menu_id = roleMenu.getMenu_id();
            SysMenu sysMenu = sysMenuService.getById(menu_id);
            //因为有层级关系--需要用到vo
            //将单个对象拷贝到SysMenuVo中
            SysMenuVo sysMenuVo = new SysMenuVo();
            BeanUtils.copyProperties(sysMenu, sysMenuVo);
            return sysMenuVo;
        }).collect(Collectors.toList());

        //一堆的 MenuVo对象需要分层级塞到对应的下级列表中
        //方法一:不考虑层级顺序遍历所有对象只要找到自己的父类就吧自己塞到父类的下级列表中---失败
        //方法2:分层级一层一层找到对象后从第3层开始塞
        List<SysMenuVo> sysMenuVos = sysMenuService.setAllinRightPlace(sysMenuVoList);
        //排序完成后塞入返回对象
        roleVo.setAuthList(sysMenuVos);

        return ResultData.ok("查询角色详情", roleVo);
    }

    /**
     * 角色修改
     *
     * @return
     */
    @PostMapping("update")
    public ResultData update(@RequestBody RoleVo roleVo) {
        log.info("修改角色" + roleVo.toString());
//首先删除所有关联表中的这个roleId的内容[准备全部重新插入而不是增加几条]
        LambdaQueryWrapper<SysRoleMenu> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        String roleId = roleVo.getId();
        lambdaQueryWrapper.eq(SysRoleMenu::getRole_id, roleId);
        sysRoleMenuService.remove(lambdaQueryWrapper);
        //将 新的关联信息存入RoleMenu关联表,其中roleId都一样而menuId不同[全在menuids列表中]
        List<String> menuids = roleVo.getMenuids();
        List<SysRoleMenu> roleMenuList = menuids.stream().map(menuId -> {
            SysRoleMenu roleMenu = new SysRoleMenu();
            roleMenu.setMenu_id(menuId);
            roleMenu.setRole_id(roleId);

            return roleMenu;
        }).collect(Collectors.toList());
        sysRoleMenuService.saveBatch(roleMenuList);
//修改完RoleMenu关联表后再更新Role表
        boolean b = roleService.updateById(roleVo);
        if (false==b){
            return ResultData.error("Role更新失败");
        }

        return ResultData.ok("修改完成", "");
    }

    /**
     * 角色添加
     *
     * @param roleVo
     * @return
     */
    @PostMapping("add")
    public ResultData add(@RequestBody RoleVo roleVo) {
        log.info("添加请求" + roleVo.toString());
        //现在role表进行新增
        boolean save = roleService.save(roleVo);
        if (false==save){
            return ResultData.error("Role保存失败");
        }
        //还要将role_menu关系表也存上
        //将 新的关联信息存入RoleMenu关联表,其中roleId都一样而menuId不同[全在menuids列表中]
        String roleId = roleVo.getId();
        List<String> menuids = roleVo.getMenuids();
        List<SysRoleMenu> roleMenuList = menuids.stream().map(menuId -> {
            SysRoleMenu roleMenu = new SysRoleMenu();
            roleMenu.setMenu_id(menuId);
            roleMenu.setRole_id(roleId);

            return roleMenu;
        }).collect(Collectors.toList());
        sysRoleMenuService.saveBatch(roleMenuList);

        return ResultData.ok("新增成功","");
    }

    /**
     * 角色删除
     * @param id
     * @return
     */
    @GetMapping("del")
    @Transactional
    public ResultData del(@RequestParam String id){
        //删除role表+删除Role_menu表
        boolean b = roleService.removeById(id);
        if (false==b){
            return ResultData.error("Role表删除失败");
        }
        //还要删除关联表Role_menu
        //先找到全部Role_menu对象
        LambdaQueryWrapper<SysRoleMenu> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysRoleMenu::getRole_id,id);
         //删除全部   Role_menu对象
        boolean remove = sysRoleMenuService.remove(lambdaQueryWrapper);
        if (false==remove){
            return ResultData.error("SysRoleMenu表删除失败");
        }
        return ResultData.ok("删除成功","");
    }
}
